package com.sky.service.admin.impl;

import cn.hutool.core.date.DateException;
import com.alibaba.fastjson.JSON;
import com.sky.mapper.rider.CourierMapper;
import com.sky.mapper.admin.TradeOrderMapper;
import com.sky.mapper.user.MerchantMapper;
import com.sky.mapper.user.OrdersMapper;
import com.sky.pojo.Courier;
import com.sky.pojo.CourierTradeOrder;
import com.sky.pojo.Merchant;
import com.sky.pojo.Orders;
import com.sky.service.admin.OrderDispatchService;
import com.sky.service.webSocket.WebSocketServer;
import com.sky.utils.MapUtils;
import com.sky.vo.OrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderDispatchServiceImpl implements OrderDispatchService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private CourierMapper courierMapper;
    @Autowired
    private TradeOrderMapper tradeOrderMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WebSocketServer webSocketServer;

    @Override
    public Courier dispatch(Long id,Long tradeNo ,Long courierId) {
        if (null==id&&null!=tradeNo){
            Orders orders = ordersMapper.selectByTraNo(tradeNo);
            id=orders.getId();
        }
        // 通过订单id查询订单
        OrderVO orderVO = ordersMapper.selectById(id);
        Long shopId = orderVO.getShopId();
        if (null == shopId) {
            throw new DateException("商家倒闭了");
        }
        //通过商家id查询商家
        Merchant merchant = merchantMapper.selectById(shopId);
        //在职的10公里以内的骑手
        List<Courier> courierList = selectCourier(merchant);
        if (courierList!=null&&courierList.size()>0) {
            courierList = courierList.stream().filter(courier -> !courier.getId().equals(courierId)).collect(Collectors.toList());
            //统计骑手当日接单数量
            String localDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            List<Long> courierIdList = courierList.stream().map(courier -> courier.getId()).collect(Collectors.toList());
            List<Map<String, Long>> list = courierMapper.selectOrderByToday(localDate, courierIdList);
            //查到最少接单数量
            int minOrderNum = list.stream().min(new Comparator<Map<String, Long>>() {
                @Override
                public int compare(Map<String, Long> o1, Map<String, Long> o2) {
                    return o1.get("total").intValue() - o2.get("total").intValue();
                }
            }).get().get("total").intValue();
            //查询接单数量不大于最小接单数量+3的骑手
            List<Long> idList = list.stream().filter(map -> map.get("total").intValue() <= minOrderNum + 3).map(map -> map.get("id")).collect(Collectors.toList());
            //排除正在进行中的订单超过12的骑手
            idList = courierMapper.selectCourierOrdering(localDate, idList);
            //随机抽取一名幸运观众
            if (null == idList) {
                int index = new Random().nextInt(courierIdList.size());
                Long finalId = courierIdList.get(index);
                return courierMapper.selectById(finalId);
            }
            List<Long> finalList = idList;
            //不为空说明还有骑手挺过了筛选,进入最终回合.找到评分最高的
            Courier finalCourier = courierList.stream().filter(courier -> finalList.contains(courier.getId()))
                    .sorted(Comparator.comparing(Courier::getScore)).collect(Collectors.toList()).get(0);
            if (null!=tradeNo){
                tradeOrderMapper.updateTradByCourierId(tradeNo,finalCourier.getId());
                return finalCourier;
            }
            //计算骑手到手马内
            BigDecimal courierCost = BigDecimal.valueOf(0);
            if (orderVO.getDeliveryFee().doubleValue() <= 3) {
                courierCost = courierCost.add(BigDecimal.valueOf(1.5));
            } else if (courierCost.doubleValue() > 3 && courierCost.doubleValue() <= 5) {
                courierCost = courierCost.add(BigDecimal.valueOf(2.7));
            } else {
                courierCost = courierCost.add(BigDecimal.valueOf(2.7).multiply(BigDecimal.valueOf(0.7)));
            }

            //创建运单号
            CourierTradeOrder tradeOrder = CourierTradeOrder.builder()
                    .totalAmount(orderVO.getAmount())
                    .courierId(finalCourier.getId())
                    .orderNumber(orderVO.getNumber())
                    .waybillStatus(orderVO.PAID) //1 ： 待接单
                    .tradeCreateTime(LocalDateTime.now())
                    .shopAddress(merchant.getShopAddress())
                    .remark(orderVO.getRemark())
                    .customerAddress(orderVO.getAddress())  //客户地址
                    .customerExpectedDeliveryTime(orderVO.getEstimatedDeliveryTime()) //预计送达时间
                    .customerName(orderVO.getConsignee())
                    .shopName(merchant.getShopName())
                    .telephone(orderVO.getPhone())
                    .toBeMealTime(orderVO.getMealTime())
                    .income(courierCost)
                    .build();
            tradeOrderMapper.save(tradeOrder);
            HashMap<String, Object> map = new HashMap<>();
            map.put("tradeNo", orderVO.getNumber());
            map.put("code", 1);
            map.put("msg", "您有新的待接单,请及时查收！");

            String message = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(message);
            return finalCourier;
        }
        return null;
    }


    //在职的10公里以内的骑手
    private List<Courier> selectCourier(Merchant merchant) {
        String shopGeo = MapUtils.addressToLnglat(merchant.getShopAddress());
        String[] lnglat = shopGeo.split(",");
        // 以经纬度为中心，获取半径不超过最大距离的所有元素
        Point point = new Point(Double.parseDouble(lnglat[0]), Double.parseDouble(lnglat[1]));
        // 半径为80km
        Distance distance = new Distance(10, RedisGeoCommands.DistanceUnit.KILOMETERS);
        Circle circle = new Circle(point, distance);

        List<Long> courierIds = new ArrayList<>();
        GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo().radius("location2", circle);
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content = results.getContent();
        for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult : content) {
            RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
            System.out.println("名字:" + geoResultContent.getName());

            String idStr = geoResultContent.getName().toString().split("_")[1];
            courierIds.add(Long.parseLong(idStr));
        }

        //根据骑手的id查询骑手信息
        List<Courier> courierList = courierMapper.findCourierByIds(courierIds);
        return courierList;
    }
}
